package vcp.client.GUI.mvc.view.addons;

import java.awt.CardLayout;
import java.awt.Component;
import java.awt.GridLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import javax.swing.JComponent;
import javax.swing.JPanel;

import vcp.enums.Floor;

/**
 * <p>
 * card panel class builds new card layout
 * </p>
 * 
 * @author VCP team
 * 
 */
public class CardPanel extends JPanel implements ItemListener
{
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	private final HashMap <Integer, FloorPanel> floors;
	private int currentFloor;
	private final CardLayout cardLayout;

	/**
	 * constructor
	 */
	public CardPanel ()
	{
		this.cardLayout = new CardLayout();
		this.setLayout(this.cardLayout);
		this.floors = new HashMap <>();
		this.currentFloor = 1;
	}

	@SuppressWarnings ( "unused" )
	/**
	 * this method clears view
	 */
	public void clear ()
	{
		for ( Component component : this.getAllComponents() )
		{
			component = null;
		}

		this.floors.clear();
		this.currentFloor = 1;
	}

	/**
	 * method adds new panel
	 * 
	 * @param rows
	 * @param columns
	 * @param floor
	 */
	public void addPanel ( int rows, int columns, Floor floor )
	{
		final ArrayList <IndexedRowPanel> panels = new ArrayList <>();
		for ( int i = 0; i < rows; i ++ )
		{
			panels.add(new IndexedRowPanel(columns));
		}

		this.floors.put(floor.getFloorNumber(), new FloorPanel(rows, panels.toArray(new IndexedRowPanel[panels.size()])));

		this.add(this.floors.get(this.floors.size()), floor.toString());
	}

	/**
	 * add component method
	 * 
	 * @param component
	 */
	public void addComponent ( JComponent component )
	{
		if ( this.floors.get(this.currentFloor).isCapacityFull() )
		{
			this.currentFloor ++ ;
		}
		this.floors.get(this.currentFloor).addComponent(component);
	}

	/**
	 * list of components
	 * 
	 * @return list of all inner components
	 */
	public List <Component> getAllComponents ()
	{
		final List <Component> allComponents = new ArrayList <>();
		for ( final FloorPanel floorPanel : this.floors.values() )
		{
			this.remove(floorPanel);

			allComponents.addAll(floorPanel.getAllComponents());
			allComponents.add(floorPanel);
		}

		return allComponents;
	}

	@Override
	public void itemStateChanged ( ItemEvent e )
	{
		if ( ItemEvent.SELECTED == e.getStateChange() )
		{
			final Floor currentFloor = (Floor) e.getItem();
			this.cardLayout.show(this, currentFloor.toString());
		}
	}

	/**
	 * <p>
	 * private class floor panel
	 * </p>
	 * 
	 * @author VCP team
	 * 
	 */
	private class FloorPanel extends JPanel
	{
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		private final IndexedRowPanel[] indexedPanels;
		private int currentIndexedPanel;

		/**
		 * constructor
		 * 
		 * @param rows
		 * @param indexedPanels
		 */
		public FloorPanel ( int rows, IndexedRowPanel[] indexedPanels )
		{
			this.setLayout(new GridLayout(rows, 0));

			this.indexedPanels = indexedPanels;
			this.currentIndexedPanel = 0;

			for ( final IndexedRowPanel indexedColumnPanel : this.indexedPanels )
			{
				this.add(indexedColumnPanel);
			}
		}

		/**
		 * checks if capacity is full
		 * 
		 * @return true if full
		 */
		public boolean isCapacityFull ()
		{
			boolean isFull = false;
			for ( final IndexedRowPanel indexedColumnPanel : this.indexedPanels )
			{
				isFull = indexedColumnPanel.isCapacityFull();
			}

			return isFull;
		}

		/**
		 * method that adds new component
		 * 
		 * @param component
		 */
		public void addComponent ( JComponent component )
		{
			if ( this.indexedPanels[this.currentIndexedPanel].isCapacityFull() )
			{
				this.currentIndexedPanel ++ ;
			}

			this.indexedPanels[this.currentIndexedPanel].addComponent(component);
		}

		/**
		 * getter
		 * 
		 * @return list of components
		 */
		public List <Component> getAllComponents ()
		{
			final List <Component> allComponents = new ArrayList <>();
			for ( final IndexedRowPanel indexedPanel : this.indexedPanels )
			{
				this.remove(indexedPanel);

				allComponents.addAll(indexedPanel.getAllComponents());
				allComponents.add(indexedPanel);
			}

			return allComponents;
		}
	}

	/**
	 * <p>
	 * private class indexed row panel
	 * 
	 * @author VCP team
	 * 
	 */
	private class IndexedRowPanel extends JPanel
	{
		/**
		 * 
		 */
		private static final long serialVersionUID = 1L;

		private int panelCapacity;
		private final int panelMaxCapacity;

		/**
		 * constructor
		 * 
		 * @param columns
		 */
		public IndexedRowPanel ( int columns )
		{
			this.setLayout(new GridLayout(1, columns));
			this.panelMaxCapacity = columns;
			this.panelCapacity = 0;
		}

		/**
		 * check if capacity full
		 * 
		 * @return true if full
		 */
		public boolean isCapacityFull ()
		{
			return this.panelCapacity == this.panelMaxCapacity;
		}

		/**
		 * adds new component
		 * 
		 * @param component
		 */
		public void addComponent ( JComponent component )
		{
			this.panelCapacity ++ ;
			this.add(component);
		}

		/**
		 * getter
		 * 
		 * @return list of components
		 */
		public List <Component> getAllComponents ()
		{
			final List <Component> allComponents = new ArrayList <>();
			for ( final Component component : this.getComponents() )
			{
				this.remove(component);
				allComponents.add(component);
			}

			return allComponents;
		}
	}

}
